#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Config::IniFiles;
use File::Tail;
use Net::Syslog;
use Shell qw/date hostname/;

my $VERSION="2.41";

if (scalar (@ARGV) != 1 or  ! -f "$ARGV[0]") {
	print STDERR "Missing config file";
	exit 1;
}

my %cfg;
tie %cfg, 'Config::IniFiles', ( -file => $ARGV[0] );

my $TIMEOUT=60;
my $i=0;
# Spawn thread
foreach my $configBloc (keys %cfg) {
    print STDERR "THREAD $i\n";
    print STDERR "Handling '$configBloc' configuration with this thread ...\n";
    eval {threads->create ( "handleLogFile",  ($i, $configBloc))};
    print STDERR "Thread $i started...\n";
    $i++;
}

# boucle
 
do { sleep ($TIMEOUT); }while(1);

sub handleLogFile {
    my $id = shift;
    my $blocConfig=shift;
    
    my $TIMEOUT=60;
    my $MAXINTERVAL=15;
    my $RESETAFTER=60;
    my $LOGPREFIX="log2syslog";
    
    my $localCfg=$cfg{$blocConfig};
    die ("($id): No configuration item for $blocConfig") if scalar keys %$localCfg==0;

    my $enabled=$$localCfg{'enabled'};
    if ( !defined ($enabled) or $enabled ne "1") {
	print STDERR "($id): Configuration disabled for '$blocConfig' by configuration item\n";
	print STDERR "($id): Please set enabled=1 to enabled configuration for '$blocConfig'\n";
	die ("($id): Configuration disabled for '$blocConfig'\n") ;
    }
    my $dsn=$$localCfg{'dsn'};
    if ( !defined ($dsn) ) {
	print STDERR "($id): Configuration disabled for '$blocConfig' for configuration missing item 'dsn'\n";
	print STDERR "($id): Please set dsn parameter to enabled configuration for '$blocConfig'\n";
	die ("($id): Configuration disabled for '$blocConfig' due to configuration 'dsn' missing\n") ;
    }

    my $logFile=$$localCfg{'logFile'};
    #Convert into real file name
    $logFile=retrieveTrueFileName($logFile);
    unless ( defined ($logFile) and -f "$logFile" ) {
	print STDERR "($id): Configuration disabled for '$blocConfig' for configuration missing item 'logFile'\n";
	print STDERR "($id): Please set logFile parameter to enabled configuration for '$blocConfig'\n";
	print STDERR "($id): logFile parameter MUST be a existing file for configuration for '$blocConfig'\n";
	die ("($id): Configuration disabled for '$blocConfig' due to configuration 'logFile' missing\n") ;
    }

    my $maxInterval=$$localCfg{'maxInterval'};
    $maxInterval=$MAXINTERVAL unless defined $maxInterval;

    my $resetAfter=$$localCfg{'resetAfter'};
    $resetAfter=$RESETAFTER unless defined $resetAfter;

    my $logPrefix=$$localCfg{'logPrefix'};
    $logPrefix=$LOGPREFIX unless defined $logPrefix;

    my $excludePattern=$$localCfg{'excludePattern'};
    my $includePattern=$$localCfg{'includePattern'};


    print STDERR "($id): '$blocConfig' Configuration :\n";
    print STDERR "($id): \tmaxInterval=$maxInterval\n";
    print STDERR "($id): \tresetAfter=$resetAfter\n";
    print STDERR "($id): \tlogFile=$logFile\n";
    print STDERR "($id): \tlogPrefix=$logPrefix\n";
    print STDERR "($id): \texcludePattern=$excludePattern\n" if defined $excludePattern;
    print STDERR "($id): \tincludePattern=$includePattern\n" if defined $includePattern;
    print STDERR "($id): \tdsn=$dsn\n";
    print STDERR "($id): ---------------------------------------------\n";

    my $sender = parseDsn($id, $dsn, $logPrefix);


    my $file=File::Tail->new( name=> $logFile, maxinterval => $maxInterval, resetAfter=> $resetAfter);
 	my $line=undef;
 	while (defined($line=$file->read)) {
      		#print STDERR "($id) $line\n";
		print STDERR &{$sender}("$line");
		#my $f="retrieveTrueFileName";
		#$sender=\&{$f};
  	}

    print STDERR "($id): END THREAD $id\n";
}

sub retrieveTrueFileName{
	my $name=shift;
	print STDERR "Translating $name =>";
	$name =~ s/(\%HOST)/hostname/eg;
	$name =~ s/(\%host)/hostname("-s")/eg;
	$name =~ s/(\%domain)/hostname("-d")/eg;
	$name =~ s/(\%.)/date("+$1")/eg;
	$name =~ s/\n//g;
	print STDERR " $name";
	
	return $name;
}

my $syslog;
sub parseDsn {
	my $id =shift;
      	my $dsn=shift;
	my $name=shift;
	$name="log2syslog" unless defined $name;
	my $facility="local0";
	my $priority="info";
	my $server="127.0.0.1";
	my $port=514;
	
	if ( $dsn =~ /syslog:\/\/(.*?)\.(.*?)@(.*?)\:(.*)/ ) {
		$facility=$1;
		$priority=$2;
		$server=$3;
		$port=$4;
    	print STDERR "($id): DSN configuration\n";
    	print STDERR "($id): \tFacility=$facility\n";
    	print STDERR "($id): \tPriority=$priority\n";
    	print STDERR "($id): \tServer=$server\n";
    	print STDERR "($id): \tPort=$port\n";
    	print STDERR "($id): \tName=$name\n";
  	
	$syslog = new Net::Syslog(Facility=>$facility,Priority=>$priority, SyslogHost => $server, SyslogPort => $port, Name => $name);
	return \&senderSyslog;
	}
}

sub senderSyslog {
	return unless defined $syslog;
	my $msg=shift;
	#print STDERR "Message: $msg";
	#print STDERR Dumper($syslog);
	$syslog->send($msg);
}


exit 0;
